
import os
import wx

import ab_config
import ab_error
import ab_executor
import ab_file
import ab_plugins
import ab_exceptions
import ab_misc_panel
import ab_text
import ab_tree

import ab_ids as ai

from ab_statusbar import StatusBar

from wx.lib.splitter import MultiSplitterWindow
from ab_object import AtrAttribution as Attr


def _doExecutor(parent, app, plx_name, afile=None, data=None, **kws):
    executor = ab_executor.Executor(parent, app)
    ret = executor.run(afile, 'Generating',
                       plxs={ab_plugins.PlxTpGenerator: plx_name},
                       data=data, **kws)

    error = executor.getError()
    if error is not None:
        dialog = ab_error.ErrorDialog(parent, error)
        dialog.CenterOnScreen()
        dialog.ShowModal()

    return ret


class ViewerOpaque:
    def __init__(self, name=None, file_=None, accelerator=None, attribute=0):
        self.name = name
        self.file = file_
        self.attribute = attribute
        self.accelerator = accelerator or list()

    def __repr__(self):
        return '<<ViewerOpaque>: name:%s, file:%s, accelerator:%d>' % (
            self.name, self.file, len(self.accelerator))

    def getName(self):
        return self.name

    def getFile(self):
        return self.file

    def getAttribute(self):
        return self.attribute

    def getAccelerator(self):
        return self.accelerator

    def getAcceleratorOffset(self, offset):
        for k, off in enumerate(self.accelerator):
            if off >= offset:
                return k

        return 0


class ContainerViewer(MultiSplitterWindow):
    def __init__(self, parent, app):
        self.wins = dict()
        self.app = app
        MultiSplitterWindow.__init__(self, parent, -1, style=wx.SP_LIVE_UPDATE)

    def AppendWindow(self, window):
        if getattr(window, 'name') in self.wins:
            self.app.warn('<ContainerView.AppendWindow> duplicated %s' %
                          window.name)
            return

        self.wins[window.name] = window
        MultiSplitterWindow.AppendWindow(self, window)
        if hasattr(window, 'getSize'):
            self.SetSashPosition(
                len(self.wins) - 2,
                self.GetSizeTuple()[0] - window.getSize()[0] - 5)

    def DetachWindow(self, name):
        for w in self.wins:
            if w == name:
                MultiSplitterWindow.DetachWindow(self, self.wins[w])
                self.wins[w].Destroy()
                del self.wins[w]
                break


class ViewerPanel(MultiSplitterWindow):
    def __init__(self, parent, app, title, opaque, method=0, wrapper=None):
        MultiSplitterWindow.__init__(self, parent, -1, style=wx.SP_LIVE_UPDATE)

        self.app = app
        self.parent = parent
        self.opaque = opaque

        self.children = dict()
        self.cur_data = None
        self.cur_focus = None
        self.find_dialog = None

        self.app.debug('<ViewerPanel.__init__> Enter')
        self.attr = 0

        self.title = title
        self.method = method

        self.plx = self.app.readKey(ai.CfgParaPlxObject)
        if wrapper is None:
            self.wrapper = ab_exceptions.ExecWrapper(parent, True)
        else:
            self.wrapper = wrapper
        # for find function
        self.findstring = ''

        self.initControls()
        # dispatch the parent menus
        self.idmgr = self.app.getWindow().getIdsManager()
        self.idmgr.dispatchParentMenus(self)

        self.activate()
        self.app.debug('<ViewerPanel.__init__> Exit')

    def initControls(self):
        self.app.debug('<ViewerPanel.initControls> Enter')

        last_opaque = opaque = self.opaque.get('converter')
        if opaque is not None:
            self.app.debug('[initControls] Begin to create '
                           'TextViewerCtrl for "converter"')
            text_ctrl_converter = ab_text.TextViewerCtrl(
                self, self.app, opaque)
            self.app.debug('[initControls] End to create '
                           'TextViewerCtrl for "converter"')
            self.AppendWindow(text_ctrl_converter)
            text_ctrl_converter.name = 'converter'
            self.children[text_ctrl_converter.name] = text_ctrl_converter

        # handle cvt data if possible
        opaque = self.opaque.get('formatter')
        if opaque is not None:
            self.app.debug('[initControls] Begin to create '
                           'TextViewerCtrl for "formatter"')
            text_ctrl_formatter = ab_text.TextViewerCtrl(
                self, self.app, opaque)
            self.app.debug('[initControls] End to create '
                           'TextViewerCtrl for "formatter"')
            self.AppendWindow(text_ctrl_formatter)

            last_opaque = opaque
            text_ctrl_formatter.name = 'formatter'
            self.children[text_ctrl_formatter.name] = text_ctrl_formatter

        opaque = self.opaque.get('tree')
        if opaque is not None and not opaque.isEmpty():
            self.contain = ContainerViewer(self, self.app)

            self.app.debug('[initControls] Begin to create '
                           'TreeViewerCtrl for "tree"')
            tree_ctrl_tree = ab_tree.TreeViewerCtrl(
                self.contain, self, self.app,
                os.path.basename(self.title), opaque)
            self.app.debug('[initControls] End to create '
                           'TreeViewerCtrl for "tree"')
            tree_ctrl_tree.name = 'tree'
            self.children[tree_ctrl_tree.name] = tree_ctrl_tree

            self.contain.AppendWindow(tree_ctrl_tree)
            self.contain.SetOrientation(wx.HORIZONTAL)
            self.AppendWindow(self.contain)

        self.SetOrientation(wx.VERTICAL)

        self.app.debug('<ViewerPanel.initControls> Exit')

    def activate(self):
        self.app.debug('<ViewerPanel.activate> Enter')

        self.app.clearStatus()
        env = self.app.readKey(ai.CfgParaEnvObject)
        env.set('FILE', self.title)

        self.updateStatus(StatusBar.INFO_CTX)
        opaque = self.opaque.get('converter')
        if opaque is not None:
            if opaque.getName() is not None:
                self.updateStatus(StatusBar.SHORTNAME, state=opaque.getName())

            self.updateStatus(StatusBar.SIZE_CTX, state=len(opaque.getFile()))

        opaque = self.opaque.get('formatter')
        if opaque is not None:
            if opaque.getName() is not None:
                self.updateStatus(StatusBar.SHORTNAME2, state=opaque.getName())
            self.updateStatus(StatusBar.SIZE_CTX2, state=len(opaque.getFile()))

        self.app.debug('<ViewerPanel.activate> Exit')

    def close(self):
        pass

    def setSelection(self, fields, source=None):
        obj = None
        if source == self.children.get('tree'):
            obj = self.children.get('formatter')
            self.updateContainer(source, fields)
        elif source == self.children.get('formatter'):
            obj = self.children.get('tree')

        if hasattr(obj, 'setSelection'):
            obj.setSelection(fields)

    def updateContainer(self, source, fields):
        if source == self.children.get('tree') and \
                self.app.readKey(ai.CfgParaDisplayPicture):
            obj = source.GetPyData(source.GetSelection())
            attr = obj.getAttribution()
            if attr.get() & Attr.Picture:
                if len(fields) > 0:
                    opaque = self.getTreeRelativeOpaque()
                    if opaque is not None:
                        data = opaque.getFile().read(
                            fields[0].getSize(), fields[0].getStart())
                        misc = ab_misc_panel.MiscPanel(self.contain)
                        misc.update(data, self.GetSizeTuple(), type='picture')
                        # FIXME: how not to disturb the previous widgets
                        misc.Show(False)
                        misc.name = 'misc'
                        self.contain.AppendWindow(misc)
            else:
                self.contain.DetachWindow('misc')

    def updateFocus(self, source):
        if source != self.children.get('tree'):
            self.cur_focus = source

        self.updateStatus(StatusBar.VIEW_ACTIVE, source)

    def updateStatus(self, column, source=None, state=None):
        value = ''

        if column == StatusBar.INFO_CTX:  # no passed-in parameters
            indicator = list()

            for name in ('converter', 'formatter'):
                opaque = self.opaque.get(name)
                if opaque is not None:
                    if len(opaque.getAccelerator()) > 0:
                        indicator.append('P')
                    else:
                        indicator.append('B')

            if 'tree' in self.children:
                indicator.append('T')

            value = ''.join(indicator)
        elif column == StatusBar.INFO_SELECTED:  # AtrField
            value = ''
            opaque = self.getActiveOpaque()
            if opaque and opaque.getAccelerator():
                value = 'Ln: %d, ' % opaque.getAcceleratorOffset(
                    state.getStart())

            value += '0x%x, %d' % (state.getStart(), state.getSize())
        elif column == StatusBar.SIZE_CTX or column == StatusBar.SIZE_CTX2:
            value = '%d' % state
        elif column == StatusBar.VIEW_ACTIVE:  # no parameters
            if source == self.children.get('converter'):
                value = 'X'
            elif source == self.children.get('formatter'):
                value = 'V'
            else:
                value = 'T'
        elif column == StatusBar.SHORTNAME or column == StatusBar.SHORTNAME2:
            value = state

        self.app.updateStatus(column, value)

    def releaseFind(self, event=None):
        if event is None:
            self.cur_data = None

        if self.find_dialog is not None:
            self.find_dialog.Destroy()

            self.find_dialog = None

    def cpSelection(self, opaque, selection):
        choice = self.app.getChoice(
            self, 'Choose save format',
            ('Normal (binary) text', 'Hexadecimal text', 'formated plain-text')
        )

        content = ''
        listc = list()

        def __dumpWritecb(data):
            listc.append(data)

        if choice is not None:
            ofile = opaque.getFile()

            start, length = selection
            ofile.dump(start, length,
                       line=0 if choice == 0 else 16,
                       asc=(choice == 2),
                       writecb=__dumpWritecb)

            if len(listc) > 0:
                if choice == 1:
                    content = ' '.join(listc)
                else:
                    content = ''.join(listc)

        if len(content) > 0 and not wx.TheClipboard.IsOpened():
            wx.TheClipboard.Open()
            # don't set custom data object if it's plain-text
            if choice == 0 and len(opaque.getAccelerator()) == 0:
                clipdata = wx.CustomDataObject()
                clipdata.SetData(content)
                wx.TheClipboard.SetData(clipdata)
            else:
                wx.TheClipboard.SetData(wx.TextDataObject(content))

            wx.TheClipboard.Close()

    def getActiveOpaque(self):
        opaque = None
        for name in ('converter', 'formatter'):
            if self.cur_focus is self.children.get(name):
                opaque = self.opaque.get(name)
                break

        return opaque

    def getActiveComponent(self):
        component = None
        for name in ('converter', 'formatter'):
            if self.cur_focus is self.children.get(name):
                component = self.cur_focus

        return component

    def getTreeRelativeOpaque(self):
        return self.opaque.get('formatter') or self.opaque.get('converter')

    def getTreeComponent(self):
        return self.children.get('tree')

    def Update_Save(self):
        return True

    def Cmd_Save(self):
        enabled_list = list()

        if 'converter' in self.children or 'formatter' in self.children:
            enabled_list.append(self.app.SavedAsOriginal)
            if 'converter' in self.children and 'formatter' in self.children:
                enabled_list.append(self.app.SavedAsBinary)
        if 'tree' in self.children:
            enabled_list.append(self.app.SavedAsAtrTree)

        rc, save_tp = self.app.getSaveState(self.parent, enabled_list)
        if rc:
            if save_tp == self.app.SavedAsAtrTree:
                opaque = self.opaque['tree']
                _doExecutor(self.parent, self.app, 'AOF',
                            data=opaque, level=0, _text=True)
            else:
                if save_tp == self.app.SavedAsOriginal:
                    opaque = self.opaque.get('converter')
                    if opaque is None:
                        opaque = self.opaque.get('formatter')
                else:
                    opaque = self.opaque.get('formatter')

                ofile = opaque.getFile()
                dialog = wx.FileDialog(self, message="Choose a file to save",
                                       wildcard=self.plx.getExtension(),
                                       style=wx.SAVE | wx.CHANGE_DIR)

                if dialog.ShowModal() == wx.ID_OK:
                    ofile.save(dialog.GetPaths()[0])

    def Update_Saveas(self):
        return self.cur_focus is not None

    def Cmd_Saveas(self, savebin=False, field=None):
        opaque = self.getActiveOpaque()
        if opaque:
            ofile = opaque.getFile()
            if savebin:
                message = 'Choose a file to save'
            else:
                message = 'Choose a file to save as'

            dialog = wx.FileDialog(self, message=message,
                                   wildcard=self.plx.getExtension(),
                                   style=wx.SAVE | wx.CHANGE_DIR)

            if dialog.ShowModal() == wx.ID_OK:
                if field:
                    ofile.save(dialog.GetPaths()[0],
                               offset=field.getStart(),
                               length=field.getSize())
                else:
                    ofile.save(dialog.GetPaths()[0])

    def Update_DumpContent(self):
        return self.cur_focus is not None

    def Cmd_DumpContent(self):
        opaque = self.getActiveOpaque()

        if opaque is None:
            return

        ofile = opaque.getFile()
        rets = self.app.getDumpParameters(self.parent, size=len(ofile))
        if rets is None:
            return

        dialog = wx.FileDialog(self, message="Choose a file to save as",
                               wildcard=self.plx.getExtension(),
                               style=wx.SAVE | wx.CHANGE_DIR)

        if dialog.ShowModal() == wx.ID_OK:
            start, end, ascii, alignment, line_nb = rets

            ofile.save(dialog.GetPaths()[0], start, end - start,
                       line_nb, alignment, ascii)

    def Update_Find(self):
        return self.cur_focus is not None

    def Cmd_Find(self):
        def OnFind(event):
            self.flags = event.GetFlags()
            self.cur_data = event.GetFindString()

            self.cur_focus.execFind(self.cur_data, self.flags)

        self.releaseFind()

        # find_data should be "global"
        self.find_data = wx.FindReplaceData()
        self.find_data.SetFlags(wx.FR_DOWN)
        self.find_dialog = wx.FindReplaceDialog(self, self.find_data,
                                                'Find', wx.FR_NOWHOLEWORD)
        self.find_dialog.Show(True)

        self.Bind(wx.EVT_FIND, OnFind)
        self.Bind(wx.EVT_FIND_NEXT, OnFind)
        self.Bind(wx.EVT_FIND_CLOSE, self.releaseFind)

    def Update_FindPrevious(self):
        return (self.cur_focus is not None) and (self.cur_data is not None)

    def Cmd_FindPrevious(self):
        self.cur_focus.execFind(self.cur_data, self.flags & (~wx.FR_DOWN))

    def Update_FindNext(self):
        return (self.cur_focus is not None) and (self.cur_data is not None)

    def Cmd_FindNext(self):
        self.cur_focus.execFind(self.cur_data, self.flags | wx.FR_DOWN)

    def Update_Goto(self):
        return self.cur_focus is not None

    def Cmd_Goto(self):
        opaque = self.getActiveOpaque()

        if opaque is None:
            return

        curpos = 0
        ofile = opaque.getFile()
        selection = self.cur_focus.getSelection()
        if len(selection):
            curpos, _ = selection[0]

        offset = self.app.getNewPosition(self, len(ofile), curpos)
        if offset is not None:
            self.cur_focus.setOffset(offset, 1)

    def Update_Copy(self):
        if self.cur_focus is not None:
            opaque = self.cur_focus.getSelection()
            if opaque is not None and len(opaque) > 0:
                return True

        return False

    def Cmd_Copy(self):
        opaque = self.getActiveOpaque()

        if opaque is None:
            return

        selection = self.cur_focus.getSelection()
        if selection is None or len(selection) == 0:
            return

        self.cpSelection(opaque, selection[0])

    def Update_CopyItem(self, event):
        id = event.GetId()
        component = self.getTreeComponent()
        if component is not None:
            objectp = component.GetPyData(component.GetSelection())
            field = objectp.getField()
            if len(field) > 0 and field[0].getSize() > 0:
                if id == ai.id_Copy_Selection:
                    opaque = self.opaque.get(
                        'formatter', self.opaque.get('converter'))
                    return opaque is not None
                else:
                    return True

        return False

    def Cmd_CopyItem(self, event):
        id = event.GetId()
        component = self.getTreeComponent()

        data, text = None, True
        objectp = component.GetPyData(component.GetSelection())
        if id == ai.id_Copy_Subject:
            data = objectp.extract('s')
        elif id == ai.id_Copy_Description:
            data = objectp.extract('c')
        elif id == ai.id_Copy:
            data = objectp.extract('s') + ': ' + objectp.extract('c')
        else:
            zone = objectp.getField()[0]
            opaque = self.opaque.get('formatter', self.opaque.get('converter'))
            self.cpSelection(opaque, (zone.getStart(), zone.getSize()))
            return

        if data:
            wx.TheClipboard.Open()
            # don't set custom data object if it's plain-text
            if text:
                wx.TheClipboard.SetData(wx.TextDataObject(data))
            else:
                clipdata = wx.CustomDataObject()
                clipdata.SetData(data)
                wx.TheClipboard.SetData(clipdata)

            wx.TheClipboard.Close()

    def Update_OpenWithSegment(self):
        ret = False
        component = self.getTreeComponent()
        selection = component.GetSelection()
        if selection and selection.IsOk():
            obj = component.GetPyData(selection)

            fields = obj.extract('F')
            if len(fields) > 0:
                ret = fields[0].getSize() > 0

            if ret:
                opaque = self.children.get('formatter') or \
                    self.children.get('converter')
                ret = opaque is not None

        return ret

    def Cmd_OpenWithSegment(self):
        opaque = self.getTreeRelativeOpaque()

        component = self.getTreeComponent()
        obj = component.GetPyData(component.GetSelection())

        fields = obj.extract('F')
        if len(fields) > 0:
            zone = fields[0]

            # create the temporary file and send the file to 'plx_cnt_viewer'
            afile = ab_file.File(self.app, None, 'rb',
                                 afile=opaque.getFile(), zone=zone.getZone())
            filename = '%s {%d:%d}' % (opaque.getFile().getFilename(),
                                       zone.getStart(), zone.getSize())
            self.app.openDocument('plx_cnt_viewer', filename, afile=afile)

    def Update_SaveNode(self):
        component = self.getTreeComponent()
        selection = component.GetSelection()

        if selection is None or not selection.IsOk():
            return False

        return 'formatter' in self.children or 'converter' in self.children

    def Cmd_SaveBinary(self, field=None):
        self.Cmd_Saveas(True, field)

    def Cmd_SaveHex(self, field=None):
        opaque = self.getActiveOpaque()

        if opaque is not None:
            ofile = opaque.getFile()
            dialog = wx.FileDialog(self, message="Choose a file to save",
                                   wildcard=self.plx.getExtension(),
                                   style=wx.SAVE | wx.CHANGE_DIR)

            if dialog.ShowModal() == wx.ID_OK:
                if field:
                    ofile.save(dialog.GetPaths()[0], line=16,
                               offset=field.getStart(), length=field.getSize())
                else:
                    ofile.save(dialog.GetPaths()[0], line=16)

    def Cmd_SaveNode_Binary(self):
        component = self.getTreeComponent()

        objectp = component.GetPyData(component.GetSelection())
        field = objectp.getField()
        if len(field):
            self.Cmd_SaveBinary(field[0])

    def Cmd_SaveNode_Hex(self):
        component = self.getTreeComponent()

        objectp = component.GetPyData(component.GetSelection())
        field = objectp.getField()
        if len(field):
            self.Cmd_SaveHex(field[0])

    def Update_ExportWith(self):
        return self.getActiveComponent() is not None

    def Cmd_ExportWith(self, event):
        component = self.getActiveComponent()
        _doExecutor(self, self.app,
                    self.idmgr.getExportedPlxWithId(event.GetId()),
                    afile=self.opaque.get(component.name).getFile(),
                    tree=self.opaque.get('tree'))

    def Update_Expand(self):
        component = self.getTreeComponent()
        selection = component.GetSelection()
        if selection and selection.IsOk():
            return component.GetChildrenCount(selection) > 0 \
                and (not component.IsExpanded(selection))
        else:
            return False

    def Update_GenerateWith(self, event):
        component = self.getActiveComponent()
        if component is None:
            return False

        plx, _ = self.idmgr.getCreatorPlxWithId(event.GetId())

        return self.plx.getElement(plx).getShortname() == \
            self.opaque.get(component.name).getName()

    def Cmd_CreateWith(self, event):
        component = self.getActiveComponent()
        _, interface = self.idmgr.getCreatorPlxWithId(event.GetId())
        _doExecutor(self, self.app,
                    self.idmgr.getCreatorPlxWithId(event.GetId()),
                    interface=interface,
                    afile=self.opaque.get(component.name).getFile())

    def Cmd_Expand(self):
        component = self.getTreeComponent()
        component.Expand(component.GetSelection())

    def Update_ExpandAll(self):
        component = self.getTreeComponent()
        selection = component.GetSelection()
        if selection and selection.IsOk():
            return component.GetChildrenCount(selection) > 0
        else:
            return False

    def Cmd_ExpandAll(self):
        component = self.getTreeComponent()
        component.ExpandAll()

    def Update_ExpandChildren(self):
        return self.Update_Expand()

    def Cmd_ExpandChildren(self):
        component = self.getTreeComponent()
        component.ExpandAllChildren(component.GetSelection())

    def Update_Collapse(self):
        component = self.getTreeComponent()
        selection = component.GetSelection()
        if selection and selection.IsOk():
            return component.IsExpanded(selection)
        else:
            return False

    def Cmd_Collapse(self):
        component = self.getTreeComponent()

        component.Collapse(component.GetSelection())

    def Update_CollapseAll(self):
        return self.Update_Collapse()

    def Cmd_CollapseAll(self):
        component = self.getTreeComponent()

        component.CollapseAll()

    def Update_ExportNode(self):
        component = self.getTreeComponent()
        selection = component.GetSelection()
        if selection and selection.IsOk():
            return component.GetSelection() is not component.GetRootItem()
        else:
            return False

    def Cmd_ExportNode(self):
        component = self.getTreeComponent()

        data = component.GetPyData(component.GetSelection())
        # the level set to ZERO is to use the default value
        _doExecutor(self, self.app, 'AOF', data=data, Level=0, _text=True)

    def Update_ExportTree(self):
        return True

    def Cmd_ExportTree(self):
        # the level set to ZERO is to use the default value
        _doExecutor(self, self.app, 'AOF',
                    data=self.opaque['tree'], Level=0, _text=True)

    def Update_ExportWithLevel(self):
        component = self.getTreeComponent()
        selection = component.GetSelection()

        return selection is not None and selection.IsOk()

    def Cmd_ExportWithLevel(self):
        component = self.getTreeComponent()

        data = component.GetPyData(component.GetSelection())
        # don't set level to leave the action to the plug-in
        _doExecutor(self, self.app, 'AOF', data=data, _text=True)

    def Update_ExportWithJson(self):
        component = self.getTreeComponent()
        if component:
            selection = component.GetSelection()
            return selection is not None and selection.IsOk()
        else:
            return False

    def Cmd_ExportWithJson(self):
        fname = ''
        opaque = self.getTreeRelativeOpaque()

        if opaque:
            bnam, _ = os.path.splitext(opaque.getFile().getFilename())
            if bnam:
                fname = bnam + '.json'

        dialog = wx.FileDialog(
            self.parent,
            message="Save exported Json object",
            wildcard='Json Files (*.json)|*.json',
            defaultFile=fname,
            style=wx.SAVE | wx.CHANGE_DIR)

        if dialog.ShowModal() != wx.ID_OK:
            return None

        fname = dialog.GetPaths()[0]
        component = self.getTreeComponent()
        obj = component.GetPyData(component.GetSelection())

        try:
            obj.dump(fname=fname, dumpjson=True)
        except IOError:
            wx.MessageBox("cannot write to %s" % fname,
                          'Error', wx.OK | wx.CENTRE | wx.ICON_ERROR)

    def Update_ParseWith(self):
        return self.Update_OpenWithSegment()

    def Cmd_ParseWith(self, event):
        component = self.getTreeComponent()
        obj = component.GetPyData(component.GetSelection())
        fields = obj.extract('F')
        if len(fields) > 1:
            wx.MessageBox("It's a multiple field and can't be re-formatted",
                          'Error', wx.OK | wx.CENTRE | wx.ICON_ERROR)
            return

        zone = fields[0]
        if zone.getSize() > 0:
            opaque = self.getTreeRelativeOpaque()

            afile = ab_file.File(self.app, None, 'rb', afile=opaque.getFile(),
                                 zone=zone.getZone())
            executor = ab_executor.Executor(self, self.app)

            nam = self.idmgr.getParsedPlxWithId(event.GetId())
            ret = executor.run(afile, self.title,
                               plxs={ab_plugins.PlxTpFormatter: (nam,)})
            if ret:
                objtree = executor.getTreeResult()
                if objtree.hasChildren():
                    objtree.adjust(start=zone.start, recursive=True)
                    obj.update(attribute=objtree.getAttribution())
                    obj.appendChildren(objtree.getChildren(), remove=True)
                    if obj.isUpdatable():
                        elem = self.plx.getElement(objtree.extract('p'))
                        obj.update(subject=elem.getName())

                    wx.BeginBusyCursor()
                    # redraw the tree again
                    tree_ctrl_tree = self.children['tree']
                    tree_ctrl_tree.update()
                    wx.EndBusyCursor()

                    component.setSelection(fields)
                    return

            wx.MessageBox('"%s" could recognize the data segment!' % nam,
                          'Info', wx.OK | wx.CENTRE | wx.ICON_INFORMATION)
